package facepp

import (
	"fmt"
	"time"

	"github.com/go-resty/resty/v2"
)

type FaceSetResp struct {
	Faceset_token string `json:"faceset_token"`
	Time_used     int    `json:"time_used"`
	Face_count    int    `json:"face_count"`
	Face_added    int    `json:"face_added"`
	Request_id    string `json:"request_id"`
	Outer_id      string `json:"outer_id"`
}

// 创建人脸集
func (f *FacePP) CreateFaceset(displayName, outerId, tags, userData string) (*FaceSetResp, error) {
	params := make(map[string]string)
	params["api_key"] = f.ApiKey
	params["api_secret"] = f.ApiSecret
	if displayName != "" {
		params["display_name"] = displayName
	}
	if outerId != "" {
		params["outer_id"] = outerId
	}
	if tags != "" {
		params["tags"] = tags
	}
	if userData != "" {
		params["user_data"] = userData
	}

	var faceSetResp FaceSetResp
	var apiErrResp ApiErrResp
	client := resty.New()
	client.SetTimeout(10 * time.Second)
	resp, err := client.R().
		SetHeader(ACCEPT, APP_JSON).
		SetFormData(params).
		SetResult(&faceSetResp).
		SetError(&apiErrResp).
		Post(CREATE_FACE_SET_URL)
	if err != nil {
		return nil, fmt.Errorf(CallApiErrFormat2, HttpClientReqError.Code, HttpClientReqError.Message)
	}
	if resp.StatusCode() != 200 {
		return nil, fmt.Errorf(CallApiErrFormat2, resp.StatusCode(), apiErrResp.Error_message)
	}
	return &faceSetResp, nil
}

type FacesetDetailResp struct {
	Faceset_token string   `json:"faceset_token"`
	Tags          string   `json:"tags"`
	Time_used     int      `json:"time_used"`
	User_data     string   `json:"user_data"`
	Display_name  string   `json:"display_name"`
	Face_tokens   []string `json:"face_tokens"`
	Face_count    int      `json:"face_count"`
	Request_id    string   `json:"request_id"`
	Outer_id      string   `json:"outer_id"`
}

// 获取人脸集详情，facesetToken, outerId 参数二选一
func (f *FacePP) FacesetDetail(facesetToken, outerId string) (*FacesetDetailResp, error) {
	if facesetToken == "" && outerId == "" {
		return nil, fmt.Errorf(CallApiErrFormat2, ParamsInvalid.Code, fmt.Sprintf(ParamsInvalid.Message, "facesetToken or outerId"))
	}
	params := make(map[string]string)
	params["api_key"] = f.ApiKey
	params["api_secret"] = f.ApiSecret
	if facesetToken != "" {
		params["faceset_token"] = facesetToken
	}
	if outerId != "" {
		params["outer_id"] = outerId
	}

	var facesetDetailResp FacesetDetailResp
	var apiErrResp ApiErrResp
	client := resty.New()
	client.SetTimeout(10 * time.Second)
	resp, err := client.R().
		SetHeader(ACCEPT, APP_JSON).
		SetFormData(params).
		SetResult(&facesetDetailResp).
		SetError(&apiErrResp).
		Post(FACE_SET_DETAIL_URL)
	if err != nil {
		return nil, fmt.Errorf(CallApiErrFormat2, HttpClientReqError.Code, HttpClientReqError.Message)
	}
	if resp.StatusCode() != 200 {
		return nil, fmt.Errorf(CallApiErrFormat2, resp.StatusCode(), apiErrResp.Error_message)
	}
	return &facesetDetailResp, nil
}

type FacesetDeleteResp struct {
	Request_id    string `json:"request_id"`
	Faceset_token string `json:"faceset_token"`
	Outer_id      string `json:"outer_id"`
	Time_used     int    `json:"time_used"`
	Error_message string `json:"error_message"`
}

// 删除人脸集，
// facesetToken, outerId 参数二选一
// checkEmpty：是否检查FaceSet中是否存在face_token，默认值为1,不能删除
func (f *FacePP) FacesetDelete(facesetToken, outerId, checkEmpty string) (*FacesetDeleteResp, error) {
	if facesetToken == "" && outerId == "" {
		return nil, fmt.Errorf(CallApiErrFormat2, ParamsInvalid.Code, fmt.Sprintf(ParamsInvalid.Message, "facesetToken or outerId"))
	}
	params := make(map[string]string)
	params["api_key"] = f.ApiKey
	params["api_secret"] = f.ApiSecret
	if facesetToken != "" {
		params["faceset_token"] = facesetToken
	}
	if outerId != "" {
		params["outer_id"] = outerId
	}
	if checkEmpty != "" {
		params["check_empty"] = checkEmpty
	}

	var facesetDeleteResp FacesetDeleteResp
	var apiErrResp ApiErrResp
	client := resty.New()
	client.SetTimeout(10 * time.Second)
	resp, err := client.R().
		SetHeader(ACCEPT, APP_JSON).
		SetFormData(params).
		SetResult(&facesetDeleteResp).
		SetError(&apiErrResp).
		Post(FACE_SET_DELETE_URL)
	if err != nil {
		return nil, fmt.Errorf(CallApiErrFormat2, HttpClientReqError.Code, HttpClientReqError.Message)
	}
	if resp.StatusCode() != 200 {
		return nil, fmt.Errorf(CallApiErrFormat2, resp.StatusCode(), apiErrResp.Error_message)
	}
	return &facesetDeleteResp, nil
}

type FaceAddResp struct {
	Faceset_token string `json:"faceset_token"`
	Time_used     int    `json:"time_used"`
	Face_added    int    `json:"face_added"`
	Face_count    int    `json:"face_count"`
	Request_id    string `json:"request_id"`
	Outer_id      string `json:"outer_id"`
}

// 添加人脸，facesetToken, outerId 参数二选一，faceTokens：人脸token，多个用,隔开
func (f *FacePP) FaceAdd(facesetToken, outerId, faceTokens string) (*FaceAddResp, error) {
	if facesetToken == "" && outerId == "" {
		return nil, fmt.Errorf(CallApiErrFormat2, ParamsInvalid.Code, fmt.Sprintf(ParamsInvalid.Message, "facesetToken or outerId"))
	}
	params := make(map[string]string)
	params["api_key"] = f.ApiKey
	params["api_secret"] = f.ApiSecret
	if facesetToken != "" {
		params["faceset_token"] = facesetToken
	}
	if outerId != "" {
		params["outer_id"] = outerId
	}
	params["face_tokens"] = faceTokens

	var faceAddResp FaceAddResp
	var apiErrResp ApiErrResp
	client := resty.New()
	client.SetTimeout(10 * time.Second)
	resp, err := client.R().
		SetHeader(ACCEPT, APP_JSON).
		SetFormData(params).
		SetResult(&faceAddResp).
		SetError(&apiErrResp).
		Post(FACE_ADD_URL)
	if err != nil {
		return nil, fmt.Errorf(CallApiErrFormat2, HttpClientReqError.Code, HttpClientReqError.Message)
	}
	if resp.StatusCode() != 200 {
		return nil, fmt.Errorf(CallApiErrFormat2, resp.StatusCode(), apiErrResp.Error_message)
	}
	return &faceAddResp, nil
}

type FaceSetUserIdResp struct {
	Request_id    string `json:"request_id"`
	Face_token    string `json:"face_token"`
	User_id       string `json:"user_id"`
	Time_used     int    `json:"time_used"`
	Error_message string `json:"error_message"`
}

// 设置人脸属性用户ID，facesetToken:人脸token, userId:用户自定义的标识信息
func (f *FacePP) SetUserId(faceToken, userId string) (*FaceSetUserIdResp, error) {
	if faceToken == "" || userId == "" {
		return nil, fmt.Errorf(CallApiErrFormat2, ParamsInvalid.Code, fmt.Sprintf(ParamsInvalid.Message, "faceToken and userId"))
	}
	params := make(map[string]string)
	params["api_key"] = f.ApiKey
	params["api_secret"] = f.ApiSecret
	params["face_token"] = faceToken
	params["user_id"] = userId

	var faceSetUserIdResp FaceSetUserIdResp
	var apiErrResp ApiErrResp
	client := resty.New()
	client.SetTimeout(10 * time.Second)
	resp, err := client.R().
		SetHeader(ACCEPT, APP_JSON).
		SetFormData(params).
		SetResult(&faceSetUserIdResp).
		SetError(&apiErrResp).
		Post(FACE_SET_USERID_URL)
	if err != nil {
		return nil, fmt.Errorf(CallApiErrFormat2, HttpClientReqError.Code, HttpClientReqError.Message)
	}
	if resp.StatusCode() != 200 {
		return nil, fmt.Errorf(CallApiErrFormat2, resp.StatusCode(), apiErrResp.Error_message)
	}
	return &faceSetUserIdResp, nil
}
